package org.feng.handler;

import lombok.extern.slf4j.Slf4j;
import org.feng.entity.Employee;
import org.feng.entity.dto.EmployeeDTO;
import org.feng.entity.dto.GetEmpRequestDTO;
import org.feng.service.EmployeeService;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;

/**
 * 路由处理器
 *
 * @version v1.0
 * @author: fengjinsong
 * @date: 2022年06月07日 21时05分
 */
@Slf4j
@Component
public class RouterHandler {

    @Resource
    private EmployeeService employeeService;

    /**
     * GET 请求 http://localhost/webflux/hello 时调用此方法；
     *
     * @param request 请求体
     * @return 响应
     */
    public Mono<ServerResponse> hello(ServerRequest request) {
        log.info("Hello Webflux 的请求体 {}", request);
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue("Hello Webflux");
    }

    /**
     * 通过 HTTP 请求的入参id，获得想要的员工的数据
     *
     * @param request 请求体
     * @return 响应
     */
    public Mono<ServerResponse> getEmpById(ServerRequest request) {
        log.info("getEmpById 的请求体 {}", request);

        // 将接口传入的参数，转换为 Mono 对象
        Mono<GetEmpRequestDTO> requestParam = request.bodyToMono(GetEmpRequestDTO.class);
        // 消费请求参数，从 业务实现中查找数据，并消费转换获得最终响应
        Mono<EmployeeDTO> response = requestParam.map(dto -> {
            Mono<Employee> empById = employeeService.getEmpById(dto.getId());

            EmployeeDTO responseEmp = new EmployeeDTO();
            if (!Mono.empty().equals(empById)) {
                // 消费数据
                empById.subscribe(resp -> {
                    responseEmp.setName(resp.getName());
                    responseEmp.setAge(resp.getAge());
                    responseEmp.setBirthday(resp.getBirthday());
                    responseEmp.setJobNo(resp.getJobNo());
                    responseEmp.setHireDay(resp.getHireDay());
                });
            }
            return responseEmp;
        });
        return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(response, EmployeeDTO.class);
    }
}
